﻿// This software is the confidential and proprietary information of NetBay.
// Such confidential information should not be disclosed.
// NetBay copyright(c) 2011

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Workflow;
using Rio.Applications.Web.Services;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.AppCode.Helpers;

namespace Rio.Framework.Pages.Workflow.Models
{
    public class WorkflowInstanceListModel : INotifyPropertyChanged
    {
        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Fields

        private readonly Dictionary<long, Dictionary<string, string>> _indexValues =
            new Dictionary<long, Dictionary<string, string>>();

        private Dictionary<long, List<WorkflowInstance>> _childInstances = new Dictionary<long, List<WorkflowInstance>>();

        private Type _proxyType;

        private IList _workflowInstances;

        #endregion

        #region Properties

        public IList WorkflowInstances
        {
            get { return _workflowInstances; }
            private set
            {
                _workflowInstances = value;
                OnPropertyChanged("WorkflowInstances");
            }
        }

        public void RebindList()
        {
            OnPropertyChanged("WorkflowInstances");
        }

        public IDictionary<string, ProxyProperty> Properties
        {
            get { return ProxyBuilder<WorkflowInstance, Folder>.Properties; }
        }

        public IDictionary<string, ListSortDirection> SortDescriptors { get; set; }


        #endregion

        public void Clear()
        {
            ProxyBuilder<WorkflowInstance, Folder>.ClearProperties();
            _indexValues.Clear();

            if (SortDescriptors != null)
                SortDescriptors.Clear();

            if (WorkflowInstances != null)
                WorkflowInstances.Clear();
        }

        public void LoadDynamicIndex(FolderType folderType)
        {
            if (folderType != null)
            {
                Clear();

                LoadInstanceColumns();

                foreach (var index in folderType.LstIndex)
                {
                    if (index.IsVisible)
                    {
                        ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                            String.Format("index_{0}", index.Indentifier),
                            (i, p) => _indexValues[i.Identifier].ContainsKey(p) ? _indexValues[i.Identifier][p] : null,
                            (i, p, v) =>
                            {
                                if (_indexValues[i.Identifier].ContainsKey(p))
                                {
                                    _indexValues[i.Identifier][p] = v;
                                }
                            },
                            index.IndexLabel);
                    }
                }
            }

            _proxyType = ProxyBuilder<WorkflowInstance, Folder>.CreateType();
            WorkflowInstances =
                Activator.CreateInstance(typeof(ObservableCollection<>).MakeGenericType(_proxyType)) as IList;
        }

        public ProxyBase<WorkflowInstance> GetNewInstance()
        {
            return Activator.CreateInstance(_proxyType) as ProxyBase<WorkflowInstance>;
        }

        public void SetChilds(long id, List<WorkflowInstance> lol )
        {
            if(!_childInstances.ContainsKey(id))
            {
                _childInstances.Add(id, new List<WorkflowInstance>());
            }

            _childInstances[id] = lol;
        }

        public void SetIndexValues(WorkflowInstance instance, Folder folder)
        {
            for (int i = 0; i < folder.ListIndex.Count; i++)
            {
                Index currentIndex = folder.ListIndex.ElementAt(i);
                string currentIndexValue = folder.ListValues.ElementAt(i);

                if (_indexValues.Count > 0 && !_indexValues[instance.Identifier].ContainsKey(String.Format("index_{0}", currentIndex.Indentifier)))
                    _indexValues[instance.Identifier].Add(
                        String.Format("index_{0}", currentIndex.Indentifier),
                        GetFormattedValue(currentIndex, currentIndexValue));
            }

            var workflowInstanceProxy = Activator.CreateInstance(_proxyType) as ProxyBase<WorkflowInstance>;

            if (workflowInstanceProxy != null)
            {
                workflowInstanceProxy.InnerItem = instance;
                workflowInstanceProxy.AssociatedItem = folder;

                WorkflowInstances.Add(workflowInstanceProxy);
            }
        }


        public void AddNewInstance(WorkflowInstance instance)
        {
            _indexValues.Add(instance.Identifier, new Dictionary<string, string>());
        }

        private void LoadInstanceColumns()
        {
            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_State",
                    (i, p) => i.IsRead,
                    null,
                    "Etat");

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_StateLabel",
                    (i, p) => i.StateLabel,
                    null,
                    Resx.GetLabel(ResxWorkflow.State));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_Sender",
                    (i, p) => i.SendedBy,
                    null,
                    Resx.GetLabel(ResxFlowPage.SENDER));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_Date",
                    (i, p) => i.CreatedOn,
                    null,
                    Resx.GetLabel(ResxFlowPage.SENDINGDATE));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_FlowName",
                    (i, p) => i.DefinitionName,
                    null,
                    Resx.GetLabel(ResxWorkflow.FlowName));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_Event",
                    (i, p) => i.StartingConditionLabel,
                    null,
                    Resx.GetLabel(ResxWorkflow.EventSource));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_SendTo",
                    (i, p) => i.Receivers,
                    null,
                    Resx.GetLabel(ResxWorkflow.SendTo));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_Receivers",
                    (i, p) => i.GroupName,
                    null,
                    Resx.GetLabel(ResxWorkflow.Receiver));

            ProxyBuilder<WorkflowInstance, Folder>.AddProperty(
                    "GridViewWorkflowMessages_Childs",
                    (i, p) => _childInstances.ContainsKey(i.Identifier) ? _childInstances[i.Identifier] : null,
                     (i, p, v) =>
                     {
                         if (!_childInstances.ContainsKey(i.Identifier))
                         {
                             _childInstances.Add(i.Identifier, new List<WorkflowInstance>());
                         }

                         _childInstances[i.Identifier] = v;
                     },
                    Resx.GetLabel(ResxWorkflow.Receiver));

            SortDescriptors = new Dictionary<string, ListSortDirection>();
            SortDescriptors.Add("GridViewWorkflowMessages_Date", ListSortDirection.Descending);
        }

        private string GetFormattedValue(Index index, string rawValue)
        {
            string formattedValue = rawValue;

            if (!String.IsNullOrWhiteSpace(formattedValue))
                switch (index.Type)
                {
                    case (int)IndexDomainServiceEnums.IndexType.Date:
                        formattedValue = String.Format(DateStringFormatterHelper.GetDateStringFormatter(), DateTime.Parse(formattedValue));
                        break;
                }

            return formattedValue;
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}